package com.ash.servlet;

import javax.imageio.ImageIO;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * @encoding : UTF-8
 * @Time : 2020/12/1 18:44
 * @Author : Chen Chao
 * @File : JavaEE.${PACKAGE_NAME}.${NAME}.java
 * @Software : IntelliJ IDEA
 * @since : 1.8
 * 生成随机验证码
 */
@WebServlet("/CodeServlet")
public class CodeServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws  IOException {
        res.setContentType("image/jpg");

        String code = createCode(5);
        /*把生成的code进行共享*/
        this.getServletContext().setAttribute("code",code);
        boolean img = ImageIO.write(creatImage(150, 40, code),
                "jpg", res.getOutputStream());
        if (img) {
            System.out.println("验证码生成成功！");
        } else {
            System.out.println("验证码生成失败！");
        }
    }

    /***
     * 根据验证码生成图片
     * @param width 生成的验证码宽度
     * @param height 生成验证码长度
     * @param code  要生成图片的验证码
     * @return  验证码图片
     */
    public static BufferedImage creatImage(int width, int height, String code) {
        Random random = new Random();

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        /*创建画笔*/
        Graphics2D graphics = (Graphics2D) image.getGraphics();
        /*填充背景*/
        graphics.setColor(Color.ORANGE);
        graphics.fillRect(0, 0, width, height);
        /*覆盖以画出边框*/
        graphics.setColor(Color.pink);
        graphics.fillRect(1, 1, width - 1, height - 1);

        /*设置字体*/
        graphics.setFont(new Font("微软雅黑", Font.BOLD, height * 4 / 5));

        /*画上验证码*/
        /*获取验证码长度*/
        int len = code.length();

        /*获取每个字符中心纵坐标与画笔位置纵坐标也一度的数值*/
        float centerY = height / 3.0f;
        float drawY = height * 9.0f / 10;
        double angle = Math.PI / 180;

        for (int i = 0; i < len; i++) {
            /*获取随机颜色*/
            graphics.setColor(randomColor());
            /*获取随机角度(-20,20)*/
            int degree = random.nextInt() % 30;


            /*每个字符左下角横坐标*/
            float drawX = 1.0f * i * width / len;
            /*每个字符的中心横坐标，可能有偏差*/
            float centerX = drawX + width / 2.0f / len;

            /*旋转画笔*/
            graphics.rotate(degree * angle, centerX, centerY);
            /*画出字符*/
            graphics.drawString(code.substring(i, i + 1), drawX, drawY);
            /*画笔转回去*/
            graphics.rotate(-degree * angle, centerX, centerY);
        }
        /*加干扰线*/
        for (int i = 0; i < len; i++) {
            /*获取随机颜色*/
            Color color = randomColor();
            graphics.setColor(color);
            graphics.drawLine(random.nextInt(width), random.nextInt(height),
                    random.nextInt(width), random.nextInt(height));

        }
        /*加噪声点*/
        for (int i = 0; i < len * len; i++) {
            /*获取随机颜色*/
            graphics.setColor(randomColor());
            /*用小矩形画出点*/
            graphics.fillRect(random.nextInt(width), random.nextInt(height), 2, 2);
        }
        return image;
    }

    /**
     * 生成随机验证码
     *
     * @param len 要生成的验证码长度
     * @return 生成的验证码字符串
     */
    public static String createCode(int len) {
        String str = "ABCDEFGHIJKMNOPQRSTUVWXYZ";
        str += str.toLowerCase();
        str += "1234567890";
        StringBuilder stringBuilder = new StringBuilder(4);
        Random random = new Random();

        /*生成验证码*/
        for (int i = 0; i < len; i++) {
            stringBuilder.append(str.charAt(random.nextInt(str.length())));
        }
        return String.valueOf(stringBuilder);
    }

    /**
     * 生成随机颜色
     */
    public static Color randomColor() {
        Random random = new Random();
        return new Color(random.nextInt(256),
                random.nextInt(256), random.nextInt(256));
    }


}